import random

from django.db.models import Q

from cart import models, serialize
from rest_framework.views import APIView
from rest_framework.response import Response
from shop.models import course
from user.models import user
from utils.redis import redistool
import random
import datetime
from django.db import transaction
from utils.ali import AliPaySDK
import json
from .tasks import sendmsg, sendmail


# Create your views here.

class cart_add(APIView):
    def post(self, request):
        puser = request.data.get('user')
        pcourse = request.data.get('course')
        if not pcourse or not puser:
            return Response({"code": 400, "msg": "课程或用户不可为空"})

        info = models.cart.objects.filter(user__id=puser, course__id=pcourse).first()
        if info:
            return Response({"code": 400, "msg": "商品已添加"})
        result = models.cart.objects.create(user=user.objects.filter(id=puser).first(),
                                            course=course.objects.filter(id=pcourse).first())
        if result:
            return Response({"code": 200, "msg": "添加成功"})
        return Response({"code": 400, "msg": '添加失败'})


class cart_list(APIView):
    def get(self, request):
        id = request.query_params.get('id')
        if not id:
            return Response({"code": 400, "msg": "id不可以为空"})
        list = models.cart.objects.filter(user__id=id)
        serdata = serialize.cart(list, many=True).data
        return Response({"code": 200, "msg": '成功', "data": serdata})


class cart_del(APIView):
    def delete(self, request):
        id = request.query_params.get("id")
        if not id:
            return Response({"code": 400, "msg": "id不可以为空"})
        models.cart.objects.filter(id=id).delete()
        return Response({"code": 200, "msg": "删除成功"})


class change_status(APIView):
    def put(self, request):
        id = request.data.get("id")
        if not id:
            return Response({"code": 400, "msg": "id不可以为空"})
        info = models.cart.objects.filter(id=id).first()
        if not info:
            return Response({"code": 400, "msg": "id不可用"})
        info.isselect = not info.isselect
        info.save()
        return Response({"code": 200, "msg": "修改成功"})


class change_All(APIView):
    def put(self, request):
        id = request.data.get("id", "")
        flag = request.data.get("flag", False)
        if not id:
            return Response({"code": 400, "msg": "id或flag不可以为空"})
        models.cart.objects.filter(user__id=id).update(isselect=flag)
        return Response({"code": 200, "msg": "操作成功"})


class selected_cart(APIView):
    def get(self, request):
        id = request.query_params.get("id", "")
        if not id:
            return Response({"code": 400, "msg": "id不可以为空"})
        list = models.cart.objects.filter(user__id=id, isselect=True)
        serdata = serialize.cart(list, many=True).data
        return Response({"code": 200, "msg": '成功', "data": serdata})


class user_coupon(APIView):
    def get(self, request):
        id = request.query_params.get("id", "")
        if not id:
            return Response({"code": 400, "msg": "id不可以为空"})
        info = user.objects.filter(id=id).first()
        if not info:
            return Response({"code": 400, "msg": "无效用户"})
        data = user.objects.filter(id=id).values()[0]
        coupon = models.usercoupon.objects.filter(user=id, isused=False)
        sercoupon = serialize.usercoupon(coupon, many=True)
        return Response({"code": 200, "msg": '成功', "score": data['score'], "coupon": sercoupon.data})


def get_no():
    order_no = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(1000, 9999))
    return order_no


class create_order(APIView):
    @transaction.atomic
    def post(self, request):
        try:
            # 新增处理参数，设置成列表是后面可以直接序列化插入
            orderdata = {
                "user": request.data.get('user'),
                "paytype": request.data.get('paytype'),
                "score": request.data.get('score', 0),
                "usercoupon": request.data.get('coupon', 0)
            }
            # 校验必传参数
            if not orderdata['user'] or not orderdata['paytype']:
                return Response({"code": 400, "msg": "请传入user和paytype"})
            # 设置radis锁
            lock = redistool.set_lock(orderdata['user'])
            # 如果没有锁继续往下走
            if not lock:
                # 对照着model表依次处理每一个参数
                orderdata['orderno'] = get_no()
                orderdata['totalprice'] = 0
                # 找到用户选中支付的项目
                targetdata = models.cart.objects.filter(user=orderdata['user'], isselect=True)
                # 如果没有就说明用户没有选中任何订单
                if not targetdata:
                    return Response({"code": 400, "msg": "无选中的订单进行支付"})
                # 总价是所有选中课程的价格相加
                for item in targetdata:
                    orderdata['totalprice'] += item.course.realprice
                # 在处理实际支付价格，如果没有使用积分和优惠券它的初始值应该等于总价，float包裹是因为同一数值类型才能进行比较和运算
                orderdata['payprice'] = float(orderdata['totalprice'])
                # 拿到用户的积分，如果用户的积分大于接口传入的积分就有效
                userinfo = user.objects.get(id=orderdata['user'])
                if orderdata['score'] and float(userinfo.score) > float(orderdata['score']):
                    # 减去积分带来的优惠
                    orderdata['payprice'] -= float(float(orderdata['score']) / 10)
                if orderdata['usercoupon']:
                    # 如果有优惠券减去优惠券金额
                    couponinfo = models.usercoupon.objects.get(id=orderdata['usercoupon'], isused=False)
                    orderdata['payprice'] -= float(couponinfo.coupon.price)
                # 序列化直接.save()方法插入
                serdata = serialize.order(data=orderdata)
                if not serdata.is_valid():
                    return Response({"code": 400, "msg": "创建失败"})
                serdata.save()
                # 处理好订单列表后再处理订单详情列表
                for item in targetdata:
                    detailinfo = {
                        # 序列号后的属性要用[属性名]去访问
                        "order": serdata.data['id'],
                        "title": item.course.title,
                        "price": item.course.price,
                        "realprice": item.course.realprice,
                        "students": item.course.students,
                        "level": item.course.level,
                        "intro": item.course.intro,
                        "isfinish": item.course.isfinish,
                        "finishtime": item.course.finishtime,
                        "score": item.course.score,
                        "detail": item.course.detail,
                        "cover": item.course.cover,
                        "isfree": item.course.isfree,
                    }
                    # 同上序列化插入
                    serdetail = serialize.orderdetail(data=detailinfo)
                    if not serdetail.is_valid():
                        return Response({"code": 400, "msg": "创建订单失败", })
                    serdetail.save()
                # 创建订单成功后删除已经选中的列表
                targetdata.delete()
                # 所有动作做完以后把锁打开
                redistool.del_lock(orderdata['user'])
                return Response({"data": serdata.data, "code": 200, "msg": "创建订单成功"})
            return Response({"code": 400, "msg": "订单已经生成请稍后"})
        except Exception as e:
            # 处理其他异常
            return Response({"code": 400, "msg": "生成异常", "error": e})


class paylink(APIView):
    def get(self, request):
        order = request.query_params.get('order')
        if not order:
            return Response({"code": 400, "msg": "请传入订单id"})
        info = models.order.objects.filter(id=order).first()
        if not info:
            return Response({"code": 400, "msg": "未找到订单信息"})
        alipay = AliPaySDK()
        url = alipay.page_pay(info.orderno, info.payprice, '支付宝付款')
        if not url:
            return Response({"code": 400, "msg": "返回订单链接失败"})
        return Response({"msg": "ok", "code": 200, "data": url})


class paysuccess(APIView):
    def get(self, request):
        orderinfo = request.query_params.dict()
        targetinfo = orderinfo['biz_content']
        data = json.loads(targetinfo)
        print(11111, data)
        print(22222, orderinfo)
        alipay = AliPaySDK()
        flag = alipay.check_sign(orderinfo)
        if not flag:
            return Response({"code": 400, "msg": "支付失败"})
        info = models.order.objects.filter(orderno=data['out_trade_no']).first()
        info.payno = orderinfo['app_id']
        info.paytime = orderinfo['timestamp']
        info.payprice = data['total_amount']
        info.save()
        score = info.user.score
        if score:
            targetuser = user.objects.filter(id=info.user.id).first()
            targetuser.score -= score
            targetuser.save()
        coupon = info.usercoupon
        if coupon:
            usercoupon = models.usercoupon.objects.filter(coupon=coupon.id).first()
            usercoupon.isused = 1
            usercoupon.save()
        coursedata = models.orderdetail.objects.filter(order=info.id)
        ser = serialize.orderdetail(coursedata, many=True)
        return Response({"msg": "ok", "code": 200, "data": ser.data})


class testsend(APIView):
    def get(self, request):
        sendmsg.delay("张三")
        return Response("ok")


class Test(APIView):
    # authentication_classes = [MyAuthorization]#主要要用列表的形式设置类
    def get(self, request):
        # 执行异步任务
        sendmail.delay("你注册了**会员", "我很欢迎你", ["abc@163.com"])
        return Response("ok")
